package smecta.client.print.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Worker;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.print.Printer;
import javafx.print.PrinterJob;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.Mnemonic;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.converter.BigDecimalStringConverter;
import javafx.util.converter.DefaultStringConverter;
import javafx.util.converter.IntegerStringConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.relational.core.sql.In;
import org.springframework.web.bind.annotation.RestController;
import smecta.client.print.SpringbootJavafxApplication;
import smecta.client.print.common.constants.DataAcqConstant;
import smecta.client.print.common.constants.InitialSetupConstant;
import smecta.client.print.common.constants.ScaleConstant;
import smecta.client.print.domain.*;
import smecta.client.print.mapper.ScpPackageMapper;
import smecta.client.print.service.*;
import smecta.client.print.service.print.PrintService;
import smecta.client.print.util.AlertUtil;
import smecta.client.print.util.CustomTextFieldTableCell;
import smecta.client.print.util.weight.WeightSensor;

import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@RestController
public class ScpDataAcqController {

    @Autowired
    private PrintService printService;

    @Autowired
    private WeightSensor weightSensor;

    @Autowired
    private ScpPackageMapper scpPackageMapper;

    @Autowired
    private PrintSettingController printSettingController;

    @FXML
    private Label companyLabel;
    @FXML
    private VBox centerVBox;
    @FXML
    private ChoiceBox<String> packChoiceBox;
    @FXML
    private ChoiceBox<String> machineNumChoiceBox;
    @FXML
    private ChoiceBox<String> classNumChoiceBox;
    @FXML
    private ChoiceBox<String> levelChoiceBox;
    @FXML
    private ChoiceBox<BigDecimal> boxWeightChoiceBox;
    @FXML
    private ChoiceBox<BigDecimal> canWeightChoiceBox;
    @FXML
    private ChoiceBox<String> tubeColorChoiceBox;
    @FXML
    private ChoiceBox<String> formatChoiceBox;
    @FXML
    private ChoiceBox<String> electronicScaleChoiceBox;
    @FXML
    private ChoiceBox<String> batchSelectChoiceBox;
    @FXML
    private CheckBox autoReadNumBox;
    @FXML
    private CheckBox autoReduceCarWeight;
    @FXML
    private Button startButton;
    @FXML
    private TextArea realTimeWeightTextArea;

    @FXML
    private Button closeButton;
    @FXML
    private Button carWeightButton;
    @FXML
    private Button weightAllowButton;
    @FXML
    private Button addButton;
    @FXML
    private Button delButton;
    @FXML
    private Button confirmButton;
    @FXML
    private Button counterweightButton;
    @FXML
    private Button continuationButton;
    @FXML
    private Button newFormButton;
    @FXML
    private Button toVoidButton;

    @FXML
    private TableView<ScpDataAcqModel> tableView;
    @FXML
    private TableView<ScpPackage> produceTableView;

    @FXML
    private TableColumn<ScpDataAcqModel, Integer> snCol;
    @FXML
    private TableColumn<ScpDataAcqModel, String> machineNumCol;
    @FXML
    private TableColumn<ScpDataAcqModel, Integer> boxNumCol;
    @FXML
    private TableColumn<ScpDataAcqModel, BigDecimal> boxWeightCol;
    @FXML
    private TableColumn<ScpDataAcqModel, Integer> canNumCol;
    @FXML
    private TableColumn<ScpDataAcqModel, BigDecimal> canWeightCol;
    @FXML
    private TableColumn<ScpDataAcqModel, BigDecimal> grossWeightCol;
    @FXML
    private TableColumn<ScpDataAcqModel, BigDecimal> netWeightCol;
    @FXML
    private TableColumn<ScpDataAcqModel, String> tubeColorCol;
    @FXML
    private TableColumn<ScpDataAcqModel, String> dateDayCol;
    @FXML
    private TableColumn<ScpDataAcqModel, String> dateTimeCol;

    @FXML
    private TableColumn<ScpPackage, String> produceNameCol;
    @FXML
    private TableColumn<ScpPackage, String> produceSpecCol;
    @FXML
    private TableColumn<ScpPackage, String> batchNumCol;
    @FXML
    private TableColumn<ScpPackage, String> produceColorCol;

    @FXML
    private TextArea textArea1;
    @FXML
    private TextArea textArea2;
    @FXML
    private TextArea textArea3;
    @FXML
    private TextArea textArea4;
    @FXML
    private TextField inspectionPersonTextField;
    @FXML
    private TextField canNumberTextField;
    @FXML
    private TextField carWeightTextField;
    @FXML
    private TextField weightAllowTextField;
    @FXML
    private DatePicker datePicker;

    private Properties printSettings;
    private List<String> allPagesContent;
    @FXML
    private Button boxPrintButton;
    @FXML
    private Button boxBatchPrintButton;
    @FXML
    private Button codePrintButton;
    @FXML
    private Button saveButton;


    @Autowired
    private ScpDataAcqService scpDataAcqService;

    @Autowired
    private ScpProduceService scpProduceService;
    @Autowired
    private ScpSysSettingsService scpSysSettingsService;
    @Autowired
    private ScpCodeFormService scpCodeFormService;
    @Autowired
    private ScpProductSpecsService scpProductSpecsService;
    @Autowired
    private ScpProductPropertyValuelistService scpProductPropertyValuelistService;
    @Autowired
    private ScpPackageService scpPackageService;

    public static ConcurrentHashMap<String, Object> cacheMap = new ConcurrentHashMap<>();

    private Properties properties = new Properties();

    private String packDefaultValue = "";
    private String properTyBoxWeight = "";
    private String properTyCanWeight = "";
    private String properTyCanNum = "";
    private String chesiPeizhongwucha = "";
    private Date date = new Date();
    private String canStart = "";
    private String canEnd = "";
    private String netWeightStart = "";
    private String netWeightEnd = "";

    // 称到的重量（未做任何处理）
    private BigDecimal realWeight = BigDecimal.valueOf(0.00);
    private String grossWeightDecimals = "";
    private String netWeightDecimals = "";
    private String shortcutKeys = "";

    // 称到的重量（未做任何处理）
    public static AtomicBoolean couldDoNextCycle = new AtomicBoolean(true);

    @FXML
    private void initialize() {

        initButtonIcon();
        loadSettings();
        initChoiceBox();

        String companyName = properties.getProperty("companyName", "");
        companyLabel.setText(String.format("%s  客服电话：0575-12345678 欢迎使用%s管理系统",companyName,companyName));

        shortcutKeys = properties.getProperty("shortcutKey", "");

        snCol.setCellValueFactory(new PropertyValueFactory<>("sn"));
        machineNumCol.setCellValueFactory(new PropertyValueFactory<>("machineNum"));
        machineNumCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new DefaultStringConverter())));
        machineNumCol.setOnEditCommit(
                event -> event.getTableView().getItems().get(
                        event.getTablePosition().getRow()).setMachineNum(event.getNewValue())
        );

        boxNumCol.setCellValueFactory(new PropertyValueFactory<>("boxNum"));
        boxNumCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new IntegerStringConverter())));
        boxNumCol.setOnEditCommit(
                event -> event.getTableView().getItems().get(
                        event.getTablePosition().getRow()).setBoxNum(event.getNewValue())
        );

        boxWeightCol.setCellValueFactory(new PropertyValueFactory<>("boxWeight"));
        boxWeightCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new BigDecimalStringConverter())));
        boxWeightCol.setOnEditCommit(
                event -> {
                    ScpDataAcqModel scpDataAcqModel = event.getTableView().getItems().get(event.getTablePosition().getRow());
                    Integer canNum = scpDataAcqModel.getCanNum();
                    BigDecimal grossWeight = scpDataAcqModel.getGrossWeight();
                    BigDecimal canWeight = scpDataAcqModel.getCanWeight();
                    BigDecimal boxWeight = event.getNewValue();
                    BigDecimal netWeight = grossWeight.subtract(canWeight.multiply(new BigDecimal(canNum))).subtract(boxWeight);

                    scpDataAcqModel.setBoxWeight(boxWeight);
                    if (scpDataAcqModel.getTypeStatus() == 0) {
                        scpDataAcqModel.setNetWeight(netWeight);
                    }
                    event.getTableView().getItems().set(event.getTablePosition().getRow(), scpDataAcqModel);
                }
        );

        canNumCol.setCellValueFactory(new PropertyValueFactory<>("canNum"));
        canNumCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new IntegerStringConverter(), canStart, canEnd)));
        canNumCol.setOnEditCommit(
                event -> {
                    ScpDataAcqModel scpDataAcqModel = event.getTableView().getItems().get(event.getTablePosition().getRow());
                    Integer canNum = event.getNewValue();
                    BigDecimal grossWeight = scpDataAcqModel.getGrossWeight();
                    BigDecimal canWeight = scpDataAcqModel.getCanWeight();
                    BigDecimal boxWeight = scpDataAcqModel.getBoxWeight();
                    BigDecimal netWeight = grossWeight.subtract(canWeight.multiply(new BigDecimal(canNum))).subtract(boxWeight);

                    scpDataAcqModel.setCanNum(canNum);
                    if (scpDataAcqModel.getTypeStatus() == 0) {
                        scpDataAcqModel.setNetWeight(netWeight);
                    }
                    event.getTableView().getItems().set(event.getTablePosition().getRow(), scpDataAcqModel);
                }
        );

        canWeightCol.setCellValueFactory(new PropertyValueFactory<>("canWeight"));
        canWeightCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new BigDecimalStringConverter())));
        canWeightCol.setOnEditCommit(
                event -> {
                    ScpDataAcqModel scpDataAcqModel = event.getTableView().getItems().get(event.getTablePosition().getRow());
                    BigDecimal canWeight = event.getNewValue();
                    Integer canNum = scpDataAcqModel.getCanNum();
                    BigDecimal boxWeight = scpDataAcqModel.getBoxWeight();
                    BigDecimal grossWeight = scpDataAcqModel.getGrossWeight();
                    BigDecimal netWeight = grossWeight.subtract(canWeight.multiply(new BigDecimal(canNum))).subtract(boxWeight);

                    scpDataAcqModel.setCanWeight(canWeight);
                    if (scpDataAcqModel.getTypeStatus() == 0) {
                        scpDataAcqModel.setNetWeight(netWeight);
                    }
                    event.getTableView().getItems().set(event.getTablePosition().getRow(), scpDataAcqModel);
                }
        );

        grossWeightCol.setCellValueFactory(new PropertyValueFactory<>("grossWeight"));
        grossWeightCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new BigDecimalStringConverter())));
        grossWeightCol.setOnEditCommit(
                event ->
                {
                    ScpDataAcqModel scpDataAcqModel = event.getTableView().getItems().get(event.getTablePosition().getRow());
                    BigDecimal grossWeight = event.getNewValue();
                    Integer canNum = scpDataAcqModel.getCanNum();
                    BigDecimal boxWeight = scpDataAcqModel.getBoxWeight();
                    BigDecimal canWeight = scpDataAcqModel.getCanWeight();
                    BigDecimal netWeight = grossWeight.subtract(canWeight.multiply(new BigDecimal(canNum))).subtract(boxWeight);

                    if (StringUtils.isBlank(grossWeightDecimals)){
                        grossWeightDecimals = "0";
                    }
                    scpDataAcqModel.setGrossWeight(grossWeight.setScale(Integer.parseInt(grossWeightDecimals),RoundingMode.HALF_UP));
                    if (scpDataAcqModel.getTypeStatus() == 0) {
                        if (StringUtils.isBlank(netWeightDecimals)){
                            netWeightDecimals = "0";
                        }
                        scpDataAcqModel.setNetWeight(netWeight.setScale(Integer.parseInt(netWeightDecimals),RoundingMode.HALF_UP));
                    }
                    event.getTableView().getItems().set(event.getTablePosition().getRow(), scpDataAcqModel);
                }
        );

        netWeightCol.setCellValueFactory(new PropertyValueFactory<>("netWeight"));
        netWeightCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new BigDecimalStringConverter(), netWeightStart, netWeightEnd)));
        netWeightCol.setOnEditCommit(
                event -> {
                    ScpDataAcqModel scpDataAcqModel = event.getTableView().getItems().get(event.getTablePosition().getRow());
                    BigDecimal grossWeight = scpDataAcqModel.getGrossWeight();
                    Integer canNum = scpDataAcqModel.getCanNum();
                    BigDecimal boxWeight = scpDataAcqModel.getBoxWeight();
                    BigDecimal canWeight = scpDataAcqModel.getCanWeight();
                    BigDecimal netWeight = grossWeight.subtract(canWeight.multiply(new BigDecimal(canNum))).subtract(boxWeight);

                    if (scpDataAcqModel.getTypeStatus() == 0) {
                        scpDataAcqModel.setNetWeight(netWeight);
                    }
                    event.getTableView().getItems().set(event.getTablePosition().getRow(), scpDataAcqModel);
                }
        );

        tubeColorCol.setCellValueFactory(new PropertyValueFactory<>("tubeColor"));
        tubeColorCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new DefaultStringConverter())));
        tubeColorCol.setOnEditCommit(
                event -> event.getTableView().getItems().get(
                        event.getTablePosition().getRow()).setTubeColor(event.getNewValue())
        );

        dateDayCol.setCellValueFactory(new PropertyValueFactory<>("dateDay"));
        dateDayCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new DefaultStringConverter())));
        dateDayCol.setOnEditCommit(
                event -> event.getTableView().getItems().get(
                        event.getTablePosition().getRow()).setDateDay(event.getNewValue())
        );

        dateTimeCol.setCellValueFactory(new PropertyValueFactory<>("dateTime"));
        dateTimeCol.setCellFactory((col -> new CustomTextFieldTableCell<>(new DefaultStringConverter())));
        dateTimeCol.setOnEditCommit(
                event -> event.getTableView().getItems().get(
                        event.getTablePosition().getRow()).setDateTime(event.getNewValue())
        );


        produceNameCol.setCellValueFactory(new PropertyValueFactory<>("pinming"));
        produceSpecCol.setCellValueFactory(new PropertyValueFactory<>("guige"));
        batchNumCol.setCellValueFactory(new PropertyValueFactory<>("pihao"));
        produceColorCol.setCellValueFactory(new PropertyValueFactory<>("seze"));

        cacheMap.put("box", 10);
        cacheMap.put("can", Integer.parseInt(canNumberTextField.getText()));
        cacheMap.put("weight", "35.4");
        cacheMap.put("counterweight", "");
        cacheMap.put("isUse", textArea2);
        cacheMap.put("textArea1", textArea1);
        cacheMap.put("tableView", tableView);
        cacheMap.put("inspectionPersonTextField", inspectionPersonTextField);
        cacheMap.put("datePicker", datePicker);

        // 监听文本属性的变化
        textArea2.textProperty().addListener((obs, oldText, newText) -> {
            if ("定重".equals(newText)) {
                confirmAdd();
            }
        });

        produceTableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);

        // 添加选中项的监听器
        produceTableView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                textArea2.setText("");
                tubeColorChoiceBox.setValue(newValue.getGuanse());
                boxWeightChoiceBox.setValue(new BigDecimal(newValue.getXiangzhong()));
                canWeightChoiceBox.setValue(new BigDecimal(newValue.getTongzhong()));
            }
        });

        packChoiceBox.valueProperty().addListener((observable, oldValue, newValue) -> {
            analysisConfig(newValue);
            canNumberTextField.setText(properTyCanNum);
            canWeightChoiceBox.setValue(new BigDecimal(properTyCanWeight));
            boxWeightChoiceBox.setValue(new BigDecimal(properTyBoxWeight));
        });
        // 在初始化时设置文本
        realTimeWeightTextArea.setText("0.00");
        realTimeWeightTextArea.setStyle("-fx-background-color: green; -fx-font-size: 18px;");
        tableView.setEditable(true);


        autoReadNumBox.selectedProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) {
                addButton.setDisable(true);
            } else {
                addButton.setDisable(false);
            }
        });

        startButton.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.getKeyCode(shortcutKeys)) {
                startButton.fire(); // 触发按钮的动作
            }
        });

    }

    public void initButtonIcon(){
        Image image1 = new Image("icon/flash.png");
        ImageView imageView1 = new ImageView(image1);
        imageView1.setFitWidth(20); // 设置图标的宽度
        imageView1.setFitHeight(20); // 设置图标的高度
        startButton.setGraphic(imageView1);

        Image image2 = new Image("icon/add.png");
        ImageView imageView2 = new ImageView(image2);
        imageView2.setFitWidth(20); // 设置图标的宽度
        imageView2.setFitHeight(20); // 设置图标的高度
        addButton.setGraphic(imageView2);

        Image image3 = new Image("icon/close_del.png");
        ImageView imageView3 = new ImageView(image3);
        imageView3.setFitWidth(20); // 设置图标的宽度
        imageView3.setFitHeight(20); // 设置图标的高度
        delButton.setGraphic(imageView3);

        Image image4 = new Image("icon/weight.png");
        ImageView imageView4 = new ImageView(image4);
        imageView4.setFitWidth(20); // 设置图标的宽度
        imageView4.setFitHeight(20); // 设置图标的高度
        confirmButton.setGraphic(imageView4);

        Image image5 = new Image("icon/exercise.png");
        ImageView imageView5 = new ImageView(image5);
        imageView5.setFitWidth(20); // 设置图标的宽度
        imageView5.setFitHeight(20); // 设置图标的高度
        counterweightButton.setGraphic(imageView5);

        Image image6 = new Image("icon/line_end.png");
        ImageView imageView6 = new ImageView(image6);
        imageView6.setFitWidth(20); // 设置图标的宽度
        imageView6.setFitHeight(20); // 设置图标的高度
        continuationButton.setGraphic(imageView6);

        Image image7 = new Image("icon/description.png");
        ImageView imageView7 = new ImageView(image7);
        imageView7.setFitWidth(20); // 设置图标的宽度
        imageView7.setFitHeight(20); // 设置图标的高度
        newFormButton.setGraphic(imageView7);

        Image image8 = new Image("icon/cancel.png");
        ImageView imageView8 = new ImageView(image8);
        imageView8.setFitWidth(20); // 设置图标的宽度
        imageView8.setFitHeight(20); // 设置图标的高度
        toVoidButton.setGraphic(imageView8);

        Image image9 = new Image("icon/print.png");
        ImageView imageView9 = new ImageView(image9);
        imageView9.setFitWidth(20); // 设置图标的宽度
        imageView9.setFitHeight(20); // 设置图标的高度
        boxPrintButton.setGraphic(imageView9);

        Image image10 = new Image("icon/print.png");
        ImageView imageView10 = new ImageView(image10);
        imageView10.setFitWidth(20); // 设置图标的宽度
        imageView10.setFitHeight(20); // 设置图标的高度
        boxBatchPrintButton.setGraphic(imageView10);

        Image image11 = new Image("icon/print.png");
        ImageView imageView11 = new ImageView(image11);
        imageView11.setFitWidth(20); // 设置图标的宽度
        imageView11.setFitHeight(20); // 设置图标的高度
        codePrintButton.setGraphic(imageView11);

        Image image12 = new Image("icon/save.png");
        ImageView imageView12 = new ImageView(image12);
        imageView12.setFitWidth(20); // 设置图标的宽度
        imageView12.setFitHeight(20); // 设置图标的高度
        saveButton.setGraphic(imageView12);

        Image image13 = new Image("icon/move_item.png");
        ImageView imageView13 = new ImageView(image13);
        imageView13.setFitWidth(20); // 设置图标的宽度
        imageView13.setFitHeight(20); // 设置图标的高度
        closeButton.setGraphic(imageView13);

        Image image14 = new Image("icon/save_as_.png");
        ImageView imageView14 = new ImageView(image14);
        imageView14.setFitWidth(20); // 设置图标的宽度
        imageView14.setFitHeight(20); // 设置图标的高度
        weightAllowButton.setGraphic(imageView14);

        Image image15 = new Image("icon/save_as_.png");
        ImageView imageView15 = new ImageView(image15);
        imageView15.setFitWidth(20); // 设置图标的宽度
        imageView15.setFitHeight(20); // 设置图标的高度
        carWeightButton.setGraphic(imageView15);
    }

    public void updateRealtimeWeight(String weight) {
        if ("未读数".equals(startButton.getText())) {
            // 动态更新文本区域的内容
            realTimeWeightTextArea.setText("0.00");
            return;
        }

        if (!NumberUtils.isNumber(weight)) {
            return;
        }

        // 动态更新文本区域的内容
        realTimeWeightTextArea.setText(weight);

        try {
            realWeight = new BigDecimal(weight);
        } catch (Exception e) {
            log.error("updateRealtimeWeight realWeight update error:{}", e);
        }
    }

    public void addBox() {
        // 是自动读数的基础上
        if (autoReadNumBox.isSelected()) {
            if (couldDoNextCycle.get() == true) {
                couldDoNextCycle.set(false);
                handleAdd();
                handleBoxPrint();
            }
        }
    }

    public void loadSettings() {
        properties = new Properties();
        try {
            ScpSysSettings setting = scpSysSettingsService.findByKey(InitialSetupConstant.DB_DICT_KEY);
            if (Objects.isNull(setting)) {
                return ;
            }
            Properties currentProp = JSONObject.parseObject(setting.getSettingValue(), Properties.class);
            properties = currentProp;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void initChoiceBox() {
        // 设置多选框的值
        List<String> choiceBoxList = Arrays.asList(
                SysSettingsValueKeyConstant.FORMAT_CHOICE_BOX_NAME_LIST,
                SysSettingsValueKeyConstant.ELECTRONIC_SCALE_CHOICE_BOX_NAME_LIST,
                SysSettingsValueKeyConstant.CAR_WEIGHT,
                SysSettingsValueKeyConstant.INSPECTION_PERSON
        );
        Map<String, List<String>> keyValueListMap = scpSysSettingsService.getKeyValueListMap(choiceBoxList);

        List<String> packChoiceBoxNameList = Arrays.asList("大包装", "小包装", "车丝");
        List<String> machineNumChoiceBoxNameList = scpProductPropertyValuelistService.getValueListByCode(SysSettingsValueKeyConstant.MACHINE_NUM_CHOICE_BOX_NAME_LIST);
        List<String> classNumChoiceBoxNameList = scpProductPropertyValuelistService.getValueListByCode(SysSettingsValueKeyConstant.CLASS_NUM_CHOICE_BOX_NAME_LIST);
        List<String> levelChoiceBoxNameList = scpProductPropertyValuelistService.getValueListByCode(SysSettingsValueKeyConstant.LEVEL_CHOICE_BOX_NAME_LIST);
        List<String> boxWeightChoiceBoxNameList = scpProductPropertyValuelistService.getValueListByCode(SysSettingsValueKeyConstant.BOX_WEIGHT_CHOICE_BOX_NAME_LIST);
        List<String> canWeightChoiceBoxNameList = scpProductPropertyValuelistService.getValueListByCode(SysSettingsValueKeyConstant.CAN_WEIGHT_CHOICE_BOX_NAME_LIST);
        List<String> tubeColorChoiceBoxNameList = scpProductPropertyValuelistService.getValueListByCode(SysSettingsValueKeyConstant.TUBE_COLOR_CHOICE_BOX_NAME_LIST);
        List<String> formatChoiceBoxNameList = keyValueListMap.getOrDefault(SysSettingsValueKeyConstant.FORMAT_CHOICE_BOX_NAME_LIST, new ArrayList<>());
        List<String> electronicScaleChoiceBoxNameList = keyValueListMap.getOrDefault(SysSettingsValueKeyConstant.ELECTRONIC_SCALE_CHOICE_BOX_NAME_LIST, new ArrayList<>());
        List<String> inspectionPersonList = keyValueListMap.getOrDefault(SysSettingsValueKeyConstant.INSPECTION_PERSON, new ArrayList<>());
        List<String> carWeightList = keyValueListMap.getOrDefault(SysSettingsValueKeyConstant.CAR_WEIGHT, new ArrayList<>());


        List<ScpPackage> packList = scpPackageService.getListByStatus("否");
        ObservableList<ScpPackage> produceTableData = FXCollections.observableArrayList(
                packList
        );
        produceTableView.setItems(produceTableData);
        produceTableView.getSelectionModel().selectFirst();

        ScpPackage scpPackage;
        if (CollectionUtils.isEmpty(packList)) {
            scpPackage = null;
        } else {
            scpPackage = packList.get(0);
        }

        String packName = "大包装";
        if ("true".equals(properties.getProperty("da_defaultScheme", "false"))) {
            packName = "大包装";
        } else if ("true".equals(properties.getProperty("xiao_defaultScheme", "false"))) {
            packName = "小包装";
        } else if ("true".equals(properties.getProperty("chesi_defaultScheme", "false"))) {
            packName = "车丝";
        }
        analysisConfig(packName);

        // 包装
        packChoiceBox.setItems(FXCollections.observableArrayList(packChoiceBoxNameList));
        packChoiceBox.setValue(packDefaultValue);

        // 机台
        machineNumChoiceBox.setItems(FXCollections.observableArrayList(machineNumChoiceBoxNameList));
        if (scpPackage == null) {
            if (CollectionUtils.isNotEmpty(machineNumChoiceBoxNameList)) {
                machineNumChoiceBox.setValue(machineNumChoiceBoxNameList.get(0));
            }
        } else {
            machineNumChoiceBox.setValue(scpPackage.getJitaihao());
        }

        // 班次
        classNumChoiceBox.setItems(FXCollections.observableArrayList(classNumChoiceBoxNameList));
        classNumChoiceBox.setValue(classNumChoiceBoxNameList.get(0));

        // 日期
        String dateChangeTime = properties.getProperty("dateChangeTime", "00:01");
        String[] split = dateChangeTime.split(":");
        LocalTime time1 = LocalTime.of(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
        LocalTime time2 = LocalTime.of(LocalTime.now().getHour(), LocalTime.now().getMinute());
        LocalDate currentDate = LocalDate.now();
        if (time2.isBefore(time1)) {
            LocalDate previousDate = currentDate.minusDays(1);
            datePicker.setValue(previousDate);
        } else {
            datePicker.setValue(currentDate);
        }


        // 等级
        levelChoiceBox.setItems(FXCollections.observableArrayList(levelChoiceBoxNameList));
        levelChoiceBox.setValue(levelChoiceBoxNameList.get(0));

        // 检验
        if (CollectionUtils.isNotEmpty(inspectionPersonList)) {
            inspectionPersonTextField.setText(inspectionPersonList.get(0));
        } else {
            inspectionPersonTextField.setText("01");
        }

        // 箱重
        List<BigDecimal> boxWeightList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(boxWeightChoiceBoxNameList)) {
            for (String boxWeight : boxWeightChoiceBoxNameList) {
                boxWeightList.add(new BigDecimal(boxWeight));
            }
        }
        boxWeightChoiceBox.setItems(FXCollections.observableArrayList(boxWeightList));
        boxWeightChoiceBox.setValue(new BigDecimal(properTyBoxWeight));

        // 筒重
        List<BigDecimal> canWeightList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(canWeightChoiceBoxNameList)) {
            for (String canWeight : canWeightChoiceBoxNameList) {
                canWeightList.add(new BigDecimal(canWeight));
            }
        }
        canWeightChoiceBox.setItems(FXCollections.observableArrayList(canWeightList));
        canWeightChoiceBox.setValue(new BigDecimal(properTyCanWeight));

        // 筒数
        canNumberTextField.setText(properTyCanNum);

        // 管色
        tubeColorChoiceBox.setItems(FXCollections.observableArrayList(tubeColorChoiceBoxNameList));
        if (scpPackage == null) {
            if (CollectionUtils.isNotEmpty(tubeColorChoiceBoxNameList)) {
                tubeColorChoiceBox.setValue(tubeColorChoiceBoxNameList.get(0));
            }
        } else {
            tubeColorChoiceBox.setValue(scpPackage.getGuanse());
        }

        // 格式
        formatChoiceBox.setItems(FXCollections.observableArrayList(formatChoiceBoxNameList));
        formatChoiceBox.setValue(formatChoiceBoxNameList.get(0));

        // 电子秤 TODO 来自电子秤设置页面
        electronicScaleChoiceBox.setItems(FXCollections.observableArrayList(electronicScaleChoiceBoxNameList));
        electronicScaleChoiceBox.setValue(electronicScaleChoiceBoxNameList.get(0));

        // 批号
        List<String> allBatchNumList = scpProduceService.getAllBatchNumList();
        batchSelectChoiceBox.setItems(FXCollections.observableArrayList(allBatchNumList));

        // 配重允许误差
        weightAllowTextField.setText(chesiPeizhongwucha);

        // 铲车重
        if (CollectionUtils.isNotEmpty(carWeightList)) {
            carWeightTextField.setText(carWeightList.get(0));
        } else {
            carWeightTextField.setText("0");
        }

        // 自动读数
        String autoRead = properties.getProperty("autoRead", "false");
        if ("false".equals(autoRead)) {
            autoReadNumBox.setSelected(false);
        } else {
            autoReadNumBox.setSelected(true);
            // 自动读数被勾选了，那就不能手动读数，增加按钮置灰
            addButton.setDisable(true);
        }
    }

    public void analysisConfig(String packName) {
        packDefaultValue = "大包装";
        properTyBoxWeight = properties.getProperty("da_xiangzhong", "");
        properTyCanWeight = properties.getProperty("da_tongzhong", "");
        properTyCanNum = properties.getProperty("da_tongshu", "");
        chesiPeizhongwucha = properties.getProperty("da_peizhongwucha", "");
        netWeightStart = properties.getProperty("da_chengzhongf", "");
        netWeightEnd = properties.getProperty("da_chengzhongf1", "");
        canStart = properties.getProperty("da_tongzhongf", "");
        canEnd = properties.getProperty("da_tongzhongf1", "");
        grossWeightDecimals = properties.getProperty("da_maozhongDecimals", "0");
        netWeightDecimals = properties.getProperty("da_jingzhongDecimals", "0");
        if ("小包装".equals(packName)) {
            packDefaultValue = "小包装";
            properTyBoxWeight = properties.getProperty("xiao_xiangzhong", "");
            properTyCanWeight = properties.getProperty("xiao_tongzhong", "");
            properTyCanNum = properties.getProperty("xiao_tongshu", "");
            chesiPeizhongwucha = properties.getProperty("xiao_peizhongwucha", "");
            netWeightStart = properties.getProperty("xiao_chengzhongf", "");
            netWeightEnd = properties.getProperty("xiao_chengzhongf1", "");
            canStart = properties.getProperty("xiao_tongzhongf", "");
            canEnd = properties.getProperty("xiao_tongzhongf1", "");
            grossWeightDecimals = properties.getProperty("xiao_maozhongDecimals", "0");
            netWeightDecimals = properties.getProperty("xiao_jingzhongDecimals", "0");
        } else if ("车丝".equals(packName)) {
            packDefaultValue = "车丝";
            properTyBoxWeight = properties.getProperty("chesi_xiangzhong", "");
            properTyCanWeight = properties.getProperty("chesi_tongzhong", "");
            properTyCanNum = properties.getProperty("chesi_tongshu", "");
            chesiPeizhongwucha = properties.getProperty("chesi_peizhongwucha", "");
            netWeightStart = properties.getProperty("chesi_chengzhongf", "");
            netWeightEnd = properties.getProperty("chesi_chengzhongf1", "");
            canStart = properties.getProperty("chesi_tongzhongf", "");
            canEnd = properties.getProperty("chesi_tongzhongf1", "");
            grossWeightDecimals = properties.getProperty("chesi_maozhongDecimals", "0");
            netWeightDecimals = properties.getProperty("chesi_jingzhongDecimals", "0");
        }
    }

    @FXML
    private void handleBatchNumChoiceBox() {
        String value = batchSelectChoiceBox.getValue();
        if (StringUtils.isBlank(value)) {
            return;
        }
        List<ScpPackage> scpProduceModelModelList = scpProduceService.getListByBatchNum(value);

        // 创建数据并填充表格
        ObservableList<ScpPackage> produceTableData = FXCollections.observableArrayList(
                scpProduceModelModelList
        );
        produceTableView.setItems(produceTableData);
        produceTableView.getSelectionModel().selectFirst();
    }


    @FXML
    private void handleStart() {
        String text = startButton.getText();
        if ("未读数".equals(text)) {
            startButton.setText("读数中");
            couldDoNextCycle.set(true);
            weightSensor.refreshWeightSensor(ScaleConstant.SENSOR_FUNCTION_CODE_002, this);
        } else {
            startButton.setText("未读数");
            weightSensor.close();
        }
    }


    public ScpDataAcqModel makeModel() {
        String packChoiceBoxValue = packChoiceBox.getValue();
        String machineNumChoiceBoxValue = machineNumChoiceBox.getValue();
        String classNumChoiceBoxValue = classNumChoiceBox.getValue();

        String levelChoiceBoxValue = levelChoiceBox.getValue();
        String inspectionPersonTextFieldText = inspectionPersonTextField.getText();

        String tubeColorChoiceBoxValue = tubeColorChoiceBox.getValue();
        String formatChoiceBoxValue = formatChoiceBox.getValue();
        String electronicScaleChoiceBoxValue = electronicScaleChoiceBox.getValue();

        int selectedIndex = produceTableView.getSelectionModel().getSelectedIndex();
        ScpPackage scpProduceModel = produceTableView.getItems().get(selectedIndex);

        BigDecimal boxWeightChoiceBoxValue = boxWeightChoiceBox.getValue();
        BigDecimal canWeightChoiceBoxValue = canWeightChoiceBox.getValue();
        String canNumberTextFieldText = canNumberTextField.getText();

        int canNumber = Integer.parseInt(canNumberTextFieldText);


        BigDecimal grossWeight = analysisProduceWeight();

        BigDecimal allCanWeight = canWeightChoiceBoxValue.multiply(BigDecimal.valueOf(canNumber));
        BigDecimal netWeight = grossWeight.subtract(boxWeightChoiceBoxValue).subtract(allCanWeight);

        int rowCount = tableView.getItems().size();
        int boxNum;

        String sameDayContinuation = properties.getProperty("sameDayContinuation", "false");

        if (rowCount == 0) {
            if ("false".equals(sameDayContinuation)) {
                boxNum = 1;
            } else {
                boxNum = scpDataAcqService.getMaxBoxNum(inspectionPersonTextField.getText()) + 1;
            }
        } else {
            ScpDataAcqModel scpDataAcqModel = tableView.getItems().get(rowCount - 1);
            boxNum = scpDataAcqModel.getBoxNum() + 1;
        }

        ScpDataAcqModel scpDataAcqModel = new ScpDataAcqModel();
        scpDataAcqModel.setProduceId(scpProduceModel.getId());
        scpDataAcqModel.setPack(packChoiceBoxValue);
        scpDataAcqModel.setLevelName(levelChoiceBoxValue);
        scpDataAcqModel.setPerson(inspectionPersonTextFieldText);
        scpDataAcqModel.setClassNum(classNumChoiceBoxValue);
        scpDataAcqModel.setFormatName(formatChoiceBoxValue);
        scpDataAcqModel.setElectronicScaleName(electronicScaleChoiceBoxValue);
        scpDataAcqModel.setSn(rowCount + 1);
        scpDataAcqModel.setMachineNum(machineNumChoiceBoxValue);
        scpDataAcqModel.setBoxNum(boxNum);
        scpDataAcqModel.setBoxWeight(boxWeightChoiceBoxValue);
        scpDataAcqModel.setCanNum(canNumber);
        scpDataAcqModel.setCanWeight(canWeightChoiceBoxValue);
        scpDataAcqModel.setGrossWeight(grossWeight);
        scpDataAcqModel.setNetWeight(netWeight);
        scpDataAcqModel.setTubeColor(tubeColorChoiceBoxValue);
        scpDataAcqModel.setDateDay(datePicker.getValue().toString());
        scpDataAcqModel.setDateTime(new SimpleDateFormat("HH:mm:ss").format(new Date()));
        scpDataAcqModel.setTypeStatus(0);
        return scpDataAcqModel;
    }

    public void confirmAdd() {
        List<ScpDataAcqModel> list = new ArrayList<>();
        Integer box = (Integer) cacheMap.get("box");
        Integer can = (Integer) cacheMap.get("can");
        BigDecimal weight = new BigDecimal((String) cacheMap.get("weight"));
        int size = tableView.getItems().size();
        for (Integer i = 0; i < box; i++) {
            ScpDataAcqModel scpDataAcqModel = makeModel();
            scpDataAcqModel.setCanNum(can);
            scpDataAcqModel.setNetWeight(weight);
            scpDataAcqModel.setSn(size + 1);
            scpDataAcqModel.setTypeStatus(1);
            BigDecimal grossWeight = weight.add(scpDataAcqModel.getBoxWeight().add(new BigDecimal(can).multiply(scpDataAcqModel.getCanWeight())));
            scpDataAcqModel.setGrossWeight(grossWeight);
            if (CollectionUtils.isNotEmpty(list)) {
                ScpDataAcqModel scpDataAcqModel1 = list.get(i - 1);
                Integer boxNum = scpDataAcqModel1.getBoxNum();
                scpDataAcqModel.setBoxNum(boxNum + 1);
            }
            size++;
            list.add(scpDataAcqModel);
        }

        if (IsOutTableItem(list)) {
            AlertUtil.infoFinishAutoClose("超出托盘系数", 2000L);
            return;
        }
        continuationButton.setDisable(true);

        if (StringUtils.isBlank(grossWeightDecimals)){
            grossWeightDecimals = "0";
        }
        if (StringUtils.isBlank(netWeightDecimals)){
            netWeightDecimals = "0";
        }
        for (ScpDataAcqModel scpDataAcqModel : list) {
            BigDecimal grossWeight = scpDataAcqModel.getGrossWeight();
            BigDecimal netWeight = scpDataAcqModel.getNetWeight();
            scpDataAcqModel.setGrossWeight(grossWeight.setScale(Integer.parseInt(grossWeightDecimals), RoundingMode.HALF_UP));
            scpDataAcqModel.setNetWeight(netWeight.setScale(Integer.parseInt(netWeightDecimals), RoundingMode.HALF_UP));
        }
        tableView.getItems().addAll(list);
    }

    public Boolean IsOutTableItem(List<ScpDataAcqModel> list) {
        Boolean status = false;
        String items = "20";
        if (packDefaultValue.equals("小包装")) {
            items = properties.getProperty("xiao_tuopanxishu", "10");
        } else if (packDefaultValue.equals("车丝")) {
            items = properties.getProperty("chesi_tuopanxishu", "100");
        }

        Integer itemNum = Integer.parseInt(items);
        if (tableView.getItems().size() + list.size() > itemNum) {
            status = true;
        }
        return status;
    }

    /**
     * 是否自动减铲车中
     * 是：毛重 = 称到的重量 - 铲车重
     * 否：毛重 = 称到的重量
     * 净重 = 毛重 - 箱重 - 筒重 * 筒数
     */
    @FXML
    public void handleAdd() {
        List<ScpDataAcqModel> list = new ArrayList<>();
        String area2Text = textArea2.getText();
        ScpDataAcqModel scpDataAcqModel = makeModel();
        if ("定重".equals(area2Text)) {
            Integer can = (Integer) cacheMap.get("can");

            BigDecimal weight = new BigDecimal((String) cacheMap.get("weight"));
            if (tableView.getItems().size() > 0) {
                ScpDataAcqModel firstModel = tableView.getItems().get(0);
                weight = firstModel.getNetWeight();
            }

            scpDataAcqModel.setCanNum(can);
            scpDataAcqModel.setNetWeight(weight);
            scpDataAcqModel.setTypeStatus(1);
            BigDecimal grossWeight = weight.add(scpDataAcqModel.getBoxWeight().add(new BigDecimal(can).multiply(scpDataAcqModel.getCanWeight())));
            scpDataAcqModel.setGrossWeight(grossWeight);
            list.add(scpDataAcqModel);
        } else if ("配重".equals(area2Text)) {
            BigDecimal counterweight = new BigDecimal((String) cacheMap.get("counterweight"));

            if (counterweight == null && tableView.getItems().size() > 0) {
                ScpDataAcqModel firstModel = tableView.getItems().get(0);
                counterweight = firstModel.getNetWeight();
            }
            scpDataAcqModel.setNetWeight(counterweight);
            BigDecimal grossWeight = scpDataAcqModel.getBoxWeight().add(new BigDecimal(scpDataAcqModel.getCanNum()).multiply(scpDataAcqModel.getCanWeight()));
            // TODO 配重这边需不需要加上 称的重量 不清楚
            scpDataAcqModel.setGrossWeight(grossWeight);
            scpDataAcqModel.setTypeStatus(2);
            list.add(scpDataAcqModel);
        } else {
            scpDataAcqModel.setGrossWeight(realWeight);
            list.add(scpDataAcqModel);
        }
        continuationButton.setDisable(true);

        if (IsOutTableItem(list)) {
            handleSave();
            handleCreateNew();
            handleCodePrint();
            return;
        }

        if (StringUtils.isBlank(grossWeightDecimals)){
            grossWeightDecimals = "0";
        }
        if (StringUtils.isBlank(netWeightDecimals)){
            netWeightDecimals = "0";
        }
        for (ScpDataAcqModel model : list) {
            BigDecimal grossWeight = model.getGrossWeight();
            BigDecimal netWeight = model.getNetWeight();
            model.setGrossWeight(grossWeight.setScale(Integer.parseInt(grossWeightDecimals), RoundingMode.HALF_UP));
            model.setNetWeight(netWeight.setScale(Integer.parseInt(netWeightDecimals), RoundingMode.HALF_UP));
        }
        tableView.getItems().addAll(list);
    }

    /**
     * 获取商品称到的重量
     *
     * @return
     */
    public BigDecimal analysisProduceWeight() {
        boolean autoReduceCarWeightSelected = autoReduceCarWeight.isSelected();
        if (autoReduceCarWeightSelected) {
            String carWeitht = carWeightTextField.getText();
            return realWeight.subtract(new BigDecimal(carWeitht));
        }
        return realWeight;
    }

    @FXML
    private void handleDel() {
        int selectedIndex = tableView.getSelectionModel().getSelectedIndex();
        if (selectedIndex >= 0) {
            tableView.getItems().remove(selectedIndex);
            if (selectedIndex < tableView.getItems().size()) {
                tableView.getSelectionModel().clearAndSelect(selectedIndex);
            } else {
                tableView.getSelectionModel().clearAndSelect(tableView.getItems().size() - 1);
            }
        } else {
        }
    }

    @FXML
    private void handleNewForm() {
        tableView.getItems().clear();
        textArea1.setText("");
        String text = textArea2.getText();
        if (!"配重".equals(text)) {
            textArea2.setText("");
        }
        continuationButton.setDisable(false);
    }

    @FXML
    private void handleToVoid() {
        ObservableList<ScpDataAcqModel> items = tableView.getItems();
        if (CollectionUtils.isEmpty(items)) {
            return;
        }
        String codeNum = items.get(0).getCodeNum();
        if (StringUtils.isBlank(codeNum)) {
            return;
        }
        scpCodeFormService.updateStatusByCodeNum(codeNum, -1);

    }

    @FXML
    private void handleCreateNew() {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/CreateNewView.fxml"));
        loader.setControllerFactory(new Callback<Class<?>, Object>() {
            @Override
            public Object call(Class<?> param) {
                // 控制器工厂提供bean注入，此处的缺点是不能根据bean名字注入，只能通过class类型注入bean
                // 解决方案：
                // 1、SpringbootJavafxApplication.applicationContext.getBean("Bean Name", Bean.class);
                // 2、@Autowired private ApplicationContext applicationContext;
                // Object bean_name = applicationContext.getBean("bean Name", Bean.class);
                return SpringbootJavafxApplication.applicationContext.getBean(param);
            }
        });
        Stage stage = new Stage();
        Scene scene;
        try {
            scene = new Scene(loader.load());
            stage.setScene(scene);
            stage.setResizable(true);
            stage.setTitle("保存信息提示");
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void handleConfirmWeight() {

        String area2Text = textArea2.getText();
        if (!"定重".equals(area2Text)) {
            textArea1.setText("");
            textArea2.setText("");
            tableView.getItems().clear();
        }


        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/ConfirmWeightView.fxml"));
        loader.setControllerFactory(new Callback<Class<?>, Object>() {
            @Override
            public Object call(Class<?> param) {
                // 控制器工厂提供bean注入，此处的缺点是不能根据bean名字注入，只能通过class类型注入bean
                // 解决方案：
                // 1、SpringbootJavafxApplication.applicationContext.getBean("Bean Name", Bean.class);
                // 2、@Autowired private ApplicationContext applicationContext;
                // Object bean_name = applicationContext.getBean("bean Name", Bean.class);
                return SpringbootJavafxApplication.applicationContext.getBean(param);
            }
        });
        Stage stage = new Stage();
        Scene scene;
        try {
            scene = new Scene(loader.load());
            stage.setScene(scene);
            stage.setResizable(true);
            stage.setTitle("定重设置窗口");
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void handleCounterweight() {

        String text = textArea2.getText();
        if ("定重".equals(text)) {
            AlertUtil.infoFinishAutoClose("请点新单按钮后称配重", 2000L);
            return;
        }

        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/CounterweightView.fxml"));
        loader.setControllerFactory(new Callback<Class<?>, Object>() {
            @Override
            public Object call(Class<?> param) {
                // 控制器工厂提供bean注入，此处的缺点是不能根据bean名字注入，只能通过class类型注入bean
                // 解决方案：
                // 1、SpringbootJavafxApplication.applicationContext.getBean("Bean Name", Bean.class);
                // 2、@Autowired private ApplicationContext applicationContext;
                // Object bean_name = applicationContext.getBean("bean Name", Bean.class);
                return SpringbootJavafxApplication.applicationContext.getBean(param);
            }
        });
        Stage stage = new Stage();
        Scene scene;
        try {
            scene = new Scene(loader.load());
            stage.setScene(scene);
            stage.setResizable(true);
            stage.setTitle("配重窗口");
            stage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @FXML
    private void handleContinuation() {
        String differentDateContinuation = properties.getProperty("differentDateContinuation", "false");
        String codeNum = "";
        if (differentDateContinuation.equals("false")) {
            SimpleDateFormat format = new SimpleDateFormat("yyMMdd");
            LocalDate localDate = datePicker.getValue();
            Date date = new Date(localDate.atStartOfDay(TimeZone.getDefault().toZoneId()).toInstant().toEpochMilli());
            String codeNumPre = format.format(date) + inspectionPersonTextField.getText();
            codeNum = scpCodeFormService.getMaxRealCodeNum(codeNumPre);
            if (StringUtils.isBlank(codeNum)) {
                tableView.getItems().clear();
                return;
            }
        } else {
            codeNum = scpDataAcqService.getLastCodeNumListByPerson(inspectionPersonTextField.getText());
            if (StringUtils.isBlank(codeNum)) {
                tableView.getItems().clear();
                return;
            }
        }
        ScpCodeFormModel scpCodeFormModel = scpCodeFormService.findByCodeNum(codeNum);
        textArea1.setText(scpCodeFormModel.getCodeNum());
        Integer type = scpCodeFormModel.getType();
        String typeStr = "不定重";
        if (type == 1) {
            typeStr = "定重";
        } else if (type == 2) {
            typeStr = "配重";
        }
        textArea2.setText(typeStr);

        List<ScpDataAcqModel> list = scpDataAcqService.getListByCodeNum(codeNum);
        if (StringUtils.isBlank(grossWeightDecimals)){
            grossWeightDecimals = "0";
        }
        if (StringUtils.isBlank(netWeightDecimals)){
            netWeightDecimals = "0";
        }
        for (ScpDataAcqModel model : list) {
            BigDecimal grossWeight = model.getGrossWeight();
            BigDecimal netWeight = model.getNetWeight();
            model.setGrossWeight(grossWeight.setScale(Integer.parseInt(grossWeightDecimals),RoundingMode.HALF_UP));
            model.setNetWeight(netWeight.setScale(Integer.parseInt(netWeightDecimals),RoundingMode.HALF_UP));
        }
        tableView.setItems(FXCollections.observableArrayList(list));
    }

    @FXML
    public void handleSave() {
        List<ScpDataAcqModel> scpDataAcqModels = new ArrayList<>(tableView.getItems());
        if (CollectionUtils.isEmpty(scpDataAcqModels)) {
            return;
        }

        String codeNum = textArea1.getText();
        String typeStr = textArea2.getText();

        if (StringUtils.isNotBlank(codeNum)) {
            scpDataAcqService.deleteByCodeNum(codeNum);
        } else {
            codeNum = makeNextCodeNum();

            Integer type = 0;
            if ("定重".equals(typeStr)) {
                type = 1;
            } else if ("配重".equals(typeStr)) {
                type = 2;
            } else {
                typeStr = "不定重";
            }

            ScpCodeFormModel scpCodeFormModel = new ScpCodeFormModel();
            scpCodeFormModel.setCodeNum(codeNum);
            scpCodeFormModel.setType(type);
            scpCodeFormService.insertSelective(scpCodeFormModel);
        }
        for (ScpDataAcqModel model : scpDataAcqModels) {
            model.setCodeNum(codeNum);
            model.setCreator(inspectionPersonTextField.getText());
        }
        scpDataAcqService.insertSelectiveList(scpDataAcqModels);

        textArea1.setText(codeNum);
        textArea2.setText(typeStr);
        AlertUtil.infoFinishAutoClose("保存成功", 2000L);
    }

    public String makeNextCodeNum() {
        // TODO 从初始设置中获取 判定第二天的条件
        SimpleDateFormat format = new SimpleDateFormat("yyMMdd");
        LocalDate localDate = datePicker.getValue();
        Date date = new Date(localDate.atStartOfDay(TimeZone.getDefault().toZoneId()).toInstant().toEpochMilli());
        String codeNum = format.format(date) + inspectionPersonTextField.getText();
        String maxCodeNum = scpCodeFormService.getMaxCodeNum(codeNum);
        if (StringUtils.isNotBlank(maxCodeNum)) {
            codeNum = String.valueOf(Long.parseLong(maxCodeNum) + 1L);
        } else {
            codeNum = codeNum + "001";
        }
        return codeNum;
    }


    @FXML
    public void handleClose() {
        Stage stage = (Stage) closeButton.getScene().getWindow();
        stage.close();
    }


    // 一次打印一条箱单记录[这条记录是人工选择还是列表最后一行的逻辑由使用者决定]
    @FXML
    public void handleBoxPrint() {
        if (tableView.getItems().isEmpty()) {
            return;
        }
        printSingleLine(tableView.getItems().get(tableView.getItems().size() - 1));
    }

    private void printSingleLine(ScpDataAcqModel model) {
        ScpPackage scpPackage = scpPackageMapper.selectByPrimaryKey(model.getProduceId());
        Properties printSetting = printSettingController.loadFromDB();
        PTInputContext context = new PTInputContext();
        Map<String, Object> data = new HashMap<>();
        data.put("pinming", scpPackage.getPinming());
        data.put("guige", scpPackage.getGuige());
        data.put("pihao", scpPackage.getPihao());
        data.put("dengji", model.getLevelName());
        data.put("maozhong", model.getGrossWeight());
        data.put("jingzhong", model.getNetWeight());
        data.put("tongshu", model.getCanNum());
        data.put("guanse", scpPackage.getGuanse());
        data.put("seze", model.getTubeColor());
        data.put("xianghao", model.getBoxNum());
        data.put("jihao", model.getMachineNum());
        data.put("riqi", model.getDateDay());

        context.setPrinterName(printSetting.getProperty("generalBoxPrinter", ""));
        context.setTemplatePath(printSetting.getProperty("filePathFieldBox", ""));
        context.setTemplateData(data);
        printService.print(context);
        log.info("箱单打印触发!");
    }

    @FXML
    public void handleBoxBatchPrint() {
        if (tableView.getItems().isEmpty()) {
            return;
        }
        tableView.getItems().forEach(item -> {
            printSingleLine(item);
        });
    }

    @FXML
    public void handleCodePrint() {
        AlertUtil.info("码单批量打印触发!");
    }

    private void loadPrintSettings() {
        printSettings = new Properties();
        try (FileInputStream input = new FileInputStream("./boxSamplePanel.ini")) {
            printSettings.load(input);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void generatePrintContent() {
        allPagesContent = new ArrayList<>();

        Map<String, String> colNameMap = new LinkedHashMap<>();
        for (TableColumn<ScpDataAcqModel, ?> column : tableView.getColumns()) {
            String columnId = column.getId();
            if (!printSettings.getProperty(columnId + ".printable", "false").equals("true")) {
                continue;
            }
            String columnText = column.getText();
            colNameMap.put(columnId, columnText);
        }

        for (ScpDataAcqModel model : tableView.getItems()) {

            StringBuilder htmlContent = new StringBuilder("<html lang=\"zh-CN\"><head><meta charset=\"UTF-8\"><title>装 箱 单</title><style>table{border-collapse:collapse;}td{border:1px solid black;padding: 8px;text-align: center;}h1{margin: 20px 0;}</style></head><body>");

            htmlContent.append("<h1>装 箱 单</h1>");
            htmlContent.append("<table>");

            Class<?> clazz = model.getClass();

            AtomicInteger flag = new AtomicInteger(1);
            colNameMap.forEach((columnId, columnText) -> {
                int length = columnId.length();
                String fieldName = columnId.substring(0, length - 3);
                Field field;
                try {
                    field = clazz.getDeclaredField(fieldName);
                    field.setAccessible(true);
                    Object fieldValue = field.get(model);
                    if (flag.get() == 1) {
                        flag.set(2);
                        htmlContent.append(String.format("<tr><td>%s</td><td>%s</td>", columnText, fieldValue));
                    } else {
                        flag.set(1);
                        htmlContent.append(String.format("<td>%s</td><td>%s</td></tr>", columnText, fieldValue));
                    }
                } catch (NoSuchFieldException e) {
                    throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            });

            if (colNameMap.size() % 2 == 1) {
                htmlContent.append("<td></td><td></td></tr>");
            }
            htmlContent.append("</table></body></html>");

            allPagesContent.add(htmlContent.toString());
        }
        for (String s : allPagesContent) {
            System.out.println("=============================");
            System.out.println(s);
        }
    }


    private void printContent() {
        PrinterJob printerJob = PrinterJob.createPrinterJob();

        if (printerJob == null) {
            System.out.println("No printers are available.");
            return;
        }

        String defaultPrinterName = printSettings.getProperty("printerSelection", "");
        if (!defaultPrinterName.isEmpty()) {
            System.out.println("defaultPrinterName:" + defaultPrinterName);
            Printer defaultPrinter = Printer.getAllPrinters().stream()
                    .filter(printer -> printer.getName().equals(defaultPrinterName))
                    .findFirst()
                    .orElse(null);
            System.out.println("defaultPrinter:" + defaultPrinter);
            if (defaultPrinter != null) {
                printerJob.setPrinter(defaultPrinter);
            }
        }

        if (printerJob.showPrintDialog(boxPrintButton.getScene().getWindow())) {
            for (String pageContent : allPagesContent) {
                WebView webView = new WebView();
                WebEngine webEngine = webView.getEngine();
                webEngine.loadContent(pageContent);

                // Wait for the content to load
                webEngine.getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
                    if (newState == Worker.State.SUCCEEDED) {
                        // Print the loaded content
                        if (printerJob.printPage(webView)) {
                            printerJob.endJob();
                        } else {
                            System.out.println("Failed to print the page.");
                        }
                    }
                });

                try {
                    // Give some time for the content to load and render
                    Thread.sleep(100); // You can adjust the sleep time if needed
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } else {
            System.out.println("Print dialog was canceled.");
        }
    }

    @FXML
    private void handleWeightAllow() {
        String text = weightAllowTextField.getText();
        String packValue = packChoiceBox.getValue();
        if (packValue.equals("小包装")) {
            properties.setProperty("xiao_peizhongwucha", text);
        } else if (packValue.equals("车丝")) {
            properties.setProperty("chesi_peizhongwucha", text);
        } else {
            properties.setProperty("da_peizhongwucha", text);
        }
        scpSysSettingsService.updateKeyOrInit(InitialSetupConstant.DB_DICT_KEY, JSON.toJSONString(properties));
    }

    @FXML
    private void handleCarWeight() {
        String text = carWeightTextField.getText();
        scpSysSettingsService.updateKeyOrInit(SysSettingsValueKeyConstant.CAR_WEIGHT, text);
    }


}
